home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 2001 May / macformat_103_may_2001.iso / Mac OS X Shareware / Fizilla / Chrome / toolkit.jar / content / global / helperAppDldProgress.js < prev    next >
Encoding:
JavaScript  |  2001-03-26  |  13.0 KB  |  422 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "License"); you may not use this file except in
  5.  * compliance with the License.  You may obtain a copy of the License at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  10.  * for the specific language governing rights and limitations under the
  11.  * License.
  12.  *
  13.  * The Original Code is Mozilla Communicator client code,
  14.  * released March 31, 1998.
  15.  *
  16.  * The Initial Developer of the Original Code is Netscape Communications
  17.  * Corporation.  Portions created by Netscape are
  18.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  19.  * Reserved.
  20.  *
  21.  * Contributors:
  22.  *     William A. ("PowerGUI") Law <law@netscape.com>
  23.  *     Scott MacGregor <mscott@netscape.com>
  24.  */
  25.  
  26. var prefContractID             = "@mozilla.org/preferences;1";
  27. var externalProtocolServiceID = "@mozilla.org/uriloader/external-protocol-service;1";
  28.  
  29. // dialog is just an array we'll use to store various properties from the dialog document...
  30. var dialog;
  31.  
  32. // the helperAppLoader is a nsIHelperAppLauncher object
  33. var helperAppLoader;
  34.  
  35. // random global variables...
  36. var completed = false;
  37. var startTime = 0;
  38. var elapsed = 0;
  39. var interval = 500; // Update every 500 milliseconds.
  40. var lastUpdate = -interval; // Update initially.
  41. var keepProgressWindowUpBox;
  42. var targetFile;
  43.  
  44. // These are to throttle down the updating of the download rate figure.
  45. var priorRate = 0;
  46. var rateChanges = 0;
  47. var rateChangeLimit = 2;
  48.  
  49. // all progress notifications are done through our nsIWebProgressListener implementation...
  50. var progressListener = {
  51.     onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus)
  52.     {
  53.       if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
  54.       {
  55.         // we are done downloading...
  56.         completed = true;
  57.         // Indicate completion in status area.
  58.         var msg = getString( "completeMsg" );
  59.         msg = replaceInsert( msg, 1, formatSeconds( elapsed/1000 ) );
  60.         dialog.status.setAttribute("value", msg);
  61.  
  62.         // Put progress meter at 100%.
  63.         dialog.progress.setAttribute( "value", 100 );
  64.         dialog.progress.setAttribute( "mode", "normal" );
  65.         var percentMsg = getString( "percentMsg" );
  66.         percentMsg = replaceInsert( percentMsg, 1, 100 );
  67.         dialog.progressText.setAttribute("label", percentMsg);
  68.  
  69.         processEndOfDownload();
  70.       }
  71.     },
  72.  
  73.     onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
  74.     {
  75.  
  76.       var overallProgress = aCurTotalProgress;
  77.  
  78.       // Get current time.
  79.       var now = ( new Date() ).getTime();
  80.       // If interval hasn't elapsed, ignore it.
  81.       if ( now - lastUpdate < interval && aMaxTotalProgress != "-1" &&  eval(aCurTotalProgress) < eval(aMaxTotalProgress) )
  82.         return;
  83.  
  84.       // Update this time.
  85.       lastUpdate = now;
  86.  
  87.       // Update download rate.
  88.       elapsed = now - startTime;
  89.       var rate; // aCurTotalProgress/sec
  90.       if ( elapsed )
  91.         rate = ( aCurTotalProgress * 1000 ) / elapsed;
  92.       else
  93.         rate = 0;
  94.  
  95.       // Update elapsed time display.
  96.       dialog.timeElapsed.setAttribute("value", formatSeconds( elapsed / 1000 ));
  97.  
  98.       // Calculate percentage.
  99.       var percent;
  100.       if ( aMaxTotalProgress != "-1" )
  101.       {
  102.         percent = parseInt( (overallProgress*100)/aMaxTotalProgress + .5 );
  103.         if ( percent > 100 )
  104.           percent = 100;
  105.  
  106.         // Advance progress meter.
  107.         dialog.progress.setAttribute( "value", percent );
  108.       }
  109.       else
  110.       {
  111.         percent = "??";
  112.  
  113.         // Progress meter should be barber-pole in this case.
  114.         dialog.progress.setAttribute( "mode", "undetermined" );
  115.       }
  116.  
  117.       // now that we've set the progress and the time, update # bytes downloaded...
  118.       // Update status (nnK of mmK bytes at xx.xK aCurTotalProgress/sec)
  119.       var status = getString( "progressMsg" );
  120.  
  121.       // Insert 1 is the number of kilobytes downloaded so far.
  122.       status = replaceInsert( status, 1, parseInt( overallProgress/1024 + .5 ) );
  123.  
  124.       // Insert 2 is the total number of kilobytes to be downloaded (if known).
  125.       if ( aMaxTotalProgress != "-1" )
  126.          status = replaceInsert( status, 2, parseInt( aMaxTotalProgress/1024 + .5 ) );
  127.       else
  128.          status = replaceInsert( status, 2, "??" );
  129.  
  130.       if ( rate )
  131.       {
  132.         // rate is bytes/sec
  133.         var kRate = rate / 1024; // K bytes/sec;
  134.         kRate = parseInt( kRate * 10 + .5 ); // xxx (3 digits)
  135.         // Don't update too often!
  136.         if ( kRate != priorRate )
  137.         {
  138.           if ( rateChanges++ == rateChangeLimit )
  139.           {
  140.              // Time to update download rate.
  141.              priorRate = kRate;
  142.              rateChanges = 0;
  143.           }
  144.           else
  145.           {
  146.             // Stick with old rate for a bit longer.
  147.             kRate = priorRate;
  148.           }
  149.         }
  150.         else
  151.           rateChanges = 0;
  152.  
  153.          var fraction = kRate % 10;
  154.          kRate = parseInt( ( kRate - fraction ) / 10 );
  155.  
  156.          // Insert 3 is the download rate (in kilobytes/sec).
  157.          status = replaceInsert( status, 3, kRate + "." + fraction );
  158.       }
  159.       else
  160.        status = replaceInsert( status, 3, "??.?" );
  161.  
  162.       // Update status msg.
  163.       dialog.status.setAttribute("value", status);
  164.  
  165.       // Update percentage label on progress meter.
  166.       var percentMsg = getString( "percentMsg" );
  167.       percentMsg = replaceInsert( percentMsg, 1, percent );
  168.       dialog.progressText.setAttribute("value", percentMsg);
  169.  
  170.       // Update time remaining.
  171.       if ( rate && aMaxTotalProgress != "-1" )
  172.       {
  173.         var rem = ( aMaxTotalProgress - aCurTotalProgress ) / rate;
  174.             rem = parseInt( rem + .5 );
  175.             dialog.timeLeft.setAttribute("value", formatSeconds( rem ));
  176.       }
  177.       else
  178.             dialog.timeLeft.setAttribute("value", getString( "unknownTime" ));
  179.     },
  180.     onLocationChange: function(aWebProgress, aRequest, aLocation)
  181.     {
  182.       // we can ignore this notification
  183.     },
  184.     onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage)
  185.     {
  186.     },
  187.     onSecurityChange: function(aWebProgress, aRequest, state)
  188.     {
  189.     },
  190.     QueryInterface : function(iid)
  191.     {
  192.      if (iid.equals(Components.interfaces.nsIWebProgressListener) || iid.equals(Components.interfaces.nsISupportsWeakReference))
  193.       return this;
  194.  
  195.      throw Components.results.NS_NOINTERFACE;
  196.     }
  197. };
  198.  
  199. function getString( stringId ) {
  200.    // Check if we've fetched this string already.
  201.    if ( !dialog.strings[ stringId ] ) {
  202.       // Try to get it.
  203.       var elem = document.getElementById( "dialog.strings."+stringId );
  204.       try {
  205.         if ( elem
  206.            &&
  207.            elem.childNodes
  208.            &&
  209.            elem.childNodes[0]
  210.            &&
  211.            elem.childNodes[0].nodeValue ) {
  212.          dialog.strings[ stringId ] = elem.childNodes[0].nodeValue;
  213.         } else {
  214.           // If unable to fetch string, use an empty string.
  215.           dialog.strings[ stringId ] = "";
  216.         }
  217.       } catch (e) { dialog.strings[ stringId ] = ""; }
  218.    }
  219.    return dialog.strings[ stringId ];
  220. }
  221.  
  222. function formatSeconds( secs )
  223. {
  224.   // Round the number of seconds to remove fractions.
  225.   secs = parseInt( secs + .5 );
  226.   var hours = parseInt( secs/3600 );
  227.   secs -= hours*3600;
  228.   var mins = parseInt( secs/60 );
  229.   secs -= mins*60;
  230.   var result;
  231.   if ( hours )
  232.     result = getString( "longTimeFormat" );
  233.   else
  234.     result = getString( "shortTimeFormat" );
  235.  
  236.   if ( hours < 10 )
  237.      hours = "0" + hours;
  238.   if ( mins < 10 )
  239.      mins = "0" + mins;
  240.   if ( secs < 10 )
  241.      secs = "0" + secs;
  242.  
  243.   // Insert hours, minutes, and seconds into result string.
  244.   result = replaceInsert( result, 1, hours );
  245.   result = replaceInsert( result, 2, mins );
  246.   result = replaceInsert( result, 3, secs );
  247.  
  248.   return result;
  249. }
  250.  
  251. function loadDialog()
  252. {
  253.   var sourceUrlValue = {};
  254.   var initialDownloadTimeValue = {};
  255.   // targetFile is global because we are going to want re-use later one...
  256.   targetFile =  helperAppLoader.getDownloadInfo(sourceUrlValue, initialDownloadTimeValue);
  257.  
  258.   var sourceUrl = sourceUrlValue.value;
  259.   startTime = initialDownloadTimeValue.value / 1000;
  260.  
  261.   // set the elapsed time on the first pass...
  262.   var now = ( new Date() ).getTime();
  263.   // intialize the elapsed time global variable slot
  264.   elapsed = now - startTime;
  265.   // Update elapsed time display.
  266.   dialog.timeElapsed.setAttribute("value", formatSeconds( elapsed / 1000 ));
  267.   dialog.timeLeft.setAttribute("value", formatSeconds( 0 ));
  268.  
  269.   dialog.location.setAttribute("value", sourceUrlValue.value.spec );
  270.   dialog.fileName.setAttribute( "value", targetFile.unicodePath );
  271.  
  272.   var prefs = Components.classes[prefContractID].getService(Components.interfaces.nsIPref);
  273.   if (prefs)
  274.     keepProgressWindowUpBox.checked = prefs.GetBoolPref("browser.download.progressDnldDialog.keepAlive");
  275.  
  276.  
  277. }
  278.  
  279. function replaceInsert( text, index, value ) {
  280.    var result = text;
  281.    var regExp = eval( "/#"+index+"/" );
  282.    result = result.replace( regExp, value );
  283.    return result;
  284. }
  285.  
  286. function onLoad() {
  287.     // Set global variables.
  288.     helperAppLoader = window.arguments[0];
  289.  
  290.     if ( !helperAppLoader ) {
  291.         dump( "Invalid argument to downloadProgress.xul\n" );
  292.         window.close()
  293.         return;
  294.     }
  295.  
  296.     dialog = new Object;
  297.     dialog.strings = new Array;
  298.     dialog.location    = document.getElementById("dialog.location");
  299.     dialog.contentType = document.getElementById("dialog.contentType");
  300.     dialog.fileName    = document.getElementById("dialog.fileName");
  301.     dialog.status      = document.getElementById("dialog.status");
  302.     dialog.progress    = document.getElementById("dialog.progress");
  303.     dialog.progressText = document.getElementById("dialog.progressText");
  304.     dialog.timeLeft    = document.getElementById("dialog.timeLeft");
  305.     dialog.timeElapsed = document.getElementById("dialog.timeElapsed");
  306.     dialog.cancel      = document.getElementById("cancel");
  307.     keepProgressWindowUpBox = document.getElementById('keepProgressDialogUp');
  308.  
  309.     // Set up dialog button callbacks.
  310.     var object = this;
  311.     doSetOKCancel("", function () { return object.onCancel();});
  312.  
  313.     // Fill dialog.
  314.     loadDialog();
  315.  
  316.     // set our web progress listener on the helper app launcher
  317.     helperAppLoader.setWebProgressListener(progressListener);
  318.     moveToAlertPosition();
  319. }
  320.  
  321. function onUnload()
  322. {
  323.  
  324.   // remember the user's decision for the checkbox.
  325.  
  326.   var prefs = Components.classes[prefContractID].getService(Components.interfaces.nsIPref);
  327.   if (prefs)
  328.     prefs.SetBoolPref("browser.download.progressDnldDialog.keepAlive", keepProgressWindowUpBox.checked);
  329.  
  330.    // Cancel app launcher.
  331.    if (helperAppLoader)
  332.    {
  333.      try
  334.      {
  335.        helperAppLoader.closeProgressWindow();
  336.        helperAppLoader = null;
  337.      }
  338.  
  339.      catch( exception ) {}
  340.    }
  341. }
  342.  
  343. // If the user presses cancel, tell the app launcher and close the dialog...
  344. function onCancel ()
  345. {
  346.    // Cancel app launcher.
  347.    if (helperAppLoader)
  348.    {
  349.      try
  350.      {
  351.        helperAppLoader.Cancel();
  352.      }
  353.  
  354.      catch( exception ) {}
  355.    }
  356.  
  357.   // Close up dialog by returning true.
  358.   return true;
  359. }
  360.  
  361. // closeWindow should only be called from processEndOfDownload
  362. function closeWindow()
  363. {
  364.   // while the time out was fired the user may have checked the
  365.   // keep this dialog open box...so we should abort and not actually
  366.   // close the window.
  367.  
  368.   if (!keepProgressWindowUpBox.checked)
  369.     window.close();
  370.   else
  371.     setupPostProgressUI();
  372. }
  373.  
  374. function setupPostProgressUI()
  375. {
  376.   //dialog.cancel.childNodes[0].nodeValue = "Close";
  377.   // turn the cancel button into a close button
  378.   var cancelButton = document.getElementById('cancel');
  379.   if (cancelButton)
  380.   {
  381.     cancelButton.value = "Close"; // mscott -> replace with a string bundle
  382.     cancelButton.setAttribute("onclick", "window.close()");
  383.   }
  384.  
  385.   // enable the open and open folder buttons
  386.   var openFolderButton = document.getElementById('openFolder');
  387.   var openButton = document.getElementById('open');
  388.  
  389.   openFolderButton.removeAttribute("disabled");
  390.   openButton.removeAttribute("disabled");
  391. }
  392.  
  393. // when we receive a stop notification we are done reporting progress on the download
  394. // now we have to decide if the window is supposed to go away or if we are supposed to remain open
  395. // and enable the open and open folder buttons on the dialog.
  396. function processEndOfDownload()
  397. {
  398.   if (!keepProgressWindowUpBox.checked)
  399.     return window.setTimeout( "closeWindow();", 2000 ); // shut down, we are all done.
  400.  
  401.   // o.t the user has asked the window to stay open so leave it open and enable the open and open new folder buttons
  402.   setupPostProgressUI();
  403. }
  404.  
  405. function doOpen()
  406. {
  407.   try {
  408.     var localFile = targetFile.QueryInterface(Components.interfaces.nsILocalFile);
  409.     if (localFile)
  410.       localFile.launch();
  411.   } catch (ex) {}
  412. }
  413.  
  414. function doOpenFolder()
  415. {
  416.   try {
  417.     var localFile = targetFile.QueryInterface(Components.interfaces.nsILocalFile);
  418.     if (localFile)
  419.       localFile.reveal();
  420.   } catch (ex) {}
  421. }
  422.